/*******************************************************************************
 * Copyright © 2017 FriendStar.Framework 版权所有
 * Author: HYF
 * Description: FriendStar快速开发平台
 * Website：http://www.FriendStar.cn
*********************************************************************************/
using FriendStar.Domain.Entity.WareHouse;
using FriendStar.Domain.IRepository.WareHouse;
using FriendStar.Repository.WareHouse;
using System;
using System.Collections.Generic;
using System.Linq;
using SqlSugarRepository;
using FriendStar.Repository.Infrastructure;
using FriendStar.Code;
using FriendStar.Data;

namespace FriendStar.Application.WareHouse
{
    public class StoCPKConAccoForInventoryStockApp
    {
        private ICPK_41_ML_StoCPKConAccoRepository cpkConAcco = new CPK_41_ML_StoCPKConAccoRepository();
        private ICPK_42_MX_StoCPKListAccoRepository cpkListAcco = new CPK_42_MX_StoCPKListAccoRepository();
        private readonly string useUnit = Configs.GetValue("UseUnit");
        private readonly string FactoryFlag = Configs.GetValue("FactoryFlag");
        public KeyValuePair<bool, string> SaveInventoryStoreItem(CPK_41_ML_StoCPKConAccoEntity item, CPK_42_MX_StoCPKListAccoEntity detail)
        {
            if(item.FDocuTypeNO!= "CP")
            {
                return new KeyValuePair<bool, string>(false, "单据类型不正确,盘点的正确类型为CP!");
            }
            string FDocuTypeName = "成品盘存";
            //1.判断单据是否已存在，如果存在则执行更新操作，不存在则执行插入操作
            int rows = cpkConAcco.IQueryable().Where(p => p.FDocuNO == item.FDocuNO&&item.UseUnit== useUnit).Count();
            if (rows == 0)
            {
                #region 准备数据
                //生成单号
                item.FDocuNO = GetDocumentNum.GetNum(useUnit, FactoryFlag, FDocuTypeName, OperatorProvider.Provider.GetCurrent().UserCode, "", "正式");
                //台帐数据
                item.FDocuID = Guid.NewGuid().ToString("D");
                item.UseUnit = useUnit;
                item.FQuantity_KP = detail.FQuantity_KP;
                item.FAmount_KP = detail.FPrice_KP * detail.FQuantity_KP;
                item.FQuantity = detail.FQuantity;
                item.FAmount = detail.FPrice_Settle * detail.FQuantity;
                //明细数据
                detail.FDocuListID = Guid.NewGuid().ToString("D");
                detail.FDouBarCode = item.FDocuNO;
                detail.FDocuNO = item.FDocuNO;
                detail.UseUnit = item.UseUnit;
                detail.FDocuTypeNO = item.FDocuTypeNO;
                detail.FProCompanyNO = item.FHappenComNO;
                detail.FAccountDate = item.FAccountDate;
                #endregion 准备数据
                int  resultState = 1;
                #region 数据存入数据库
                var db = new RepositoryBase();
                try
                {
                    db.BeginTrans();
                    //生成单据
                    db.Insert(item);
                    db.Insert(detail);
                    //调整库存
                    var pars = db.GetParameters(new { FAccountDate = item.FAccountDate, UseUnit = useUnit, FSupplierNO = detail.FSupplierNO, FProCompanyNO = detail.FProCompanyNO, FProductionNO = detail.FProductionNO, FProductionTypeNO = detail.FProductionTypeNO, FContainerNO = detail.FContainerNO, FContainerQuantity = detail.FContainerQuantity, FQuantity = detail.FQuantity, FCreateBy = item.FCreateBy, Status = 1, resultState = 1 });
                    int index = db.GetParameterIndex(pars, "resultState");
                    //存储过程返回值暂时未用到.
                    if (index != -1)
                    {
                        pars[index].Direction = System.Data.ParameterDirection.Output;
                    }
                    db.ExecuteStoredProcedure<string>("InOutStorage_UpdateImmeStorage", pars);
                    if (index != -1)
                    {
                       if(string.IsNullOrEmpty(pars[index].Value+""))
                        {
                            resultState = 0;
                        }
                       else
                        {
                            resultState = int.Parse(pars[index].Value + "");
                        }
                    }
                    db.Commit();
                }
                catch (Exception ex)
                {
                    db.RollBack();
                    throw ex;
                }
                #endregion 数据存入数据库
            }
            else
            {
                #region 准备数据
                var oldItemData = cpkConAcco.FindEntity(p => p.FDocuNO == item.FDocuNO);
                var oldDetailData = cpkListAcco.FindEntity(p => p.FDocuNO == detail.FDocuNO && p.FProductionNO == detail.FProductionNO);
                decimal oldFQuantity_KP = 0, oldFAmount_KP = 0, oldFQuantity = 0, oldFAmount = 0;
                if (oldDetailData != null && !string.IsNullOrEmpty(oldDetailData.FDocuListID))
                {
                    oldFQuantity_KP = oldDetailData.FQuantity_KP;
                    oldFAmount_KP = oldDetailData.FPrice_KP * oldDetailData.FQuantity_KP;
                    oldFQuantity = oldDetailData.FQuantity;
                    oldFAmount = oldDetailData.FPrice_Settle * oldDetailData.FQuantity;
                }
                //台帐数据
                item.FQuantity_KP = oldItemData.FQuantity_KP + detail.FQuantity_KP - oldFQuantity_KP;
                item.FAmount_KP = oldItemData.FAmount_KP + detail.FPrice_KP * detail.FQuantity_KP - oldFAmount_KP;
                item.FQuantity = oldItemData.FQuantity + detail.FQuantity - oldFQuantity;
                item.FAmount = oldItemData.FAmount + detail.FPrice_Settle * detail.FQuantity - oldFAmount;
                //明细数据
                detail.FDocuListID = oldDetailData.FDocuListID;
                detail.FDouBarCode = item.FDocuNO;
                detail.FDocuNO = item.FDocuNO;
                detail.UseUnit = item.UseUnit;
                detail.FDocuTypeNO = item.FDocuTypeNO;
                detail.FProCompanyNO = item.FHappenComNO;
                detail.FAccountDate = item.FAccountDate;

                #endregion 准备数据

                int resultState = 1;
                #region 数据存入数据库
                var db = new RepositoryBase();
                try
                {
                    db.BeginTrans();
                    //处理明细
                    db.Update<CPK_42_MX_StoCPKListAccoEntity>(new { FQuantity_KP=detail.FQuantity_KP, FQuantity=detail.FQuantity_KP, FQuantity_RK=detail.FQuantity_KP, FPrice_KP=detail.FPrice_KP,FPrice_Settle=detail.FPrice_KP, FContainerNO=detail.FContainerNO, FContainerQuantity=detail.FContainerQuantity, FFactContent=detail.FFactContent, FDescription=detail.FDescription},p=>p.FDocuListID==detail.FDocuListID);
                    //处理台帐
                    db.Update<CPK_41_ML_StoCPKConAccoEntity>(new { FQuantity_KP=item.FQuantity_KP, FAmount_KP=item.FAmount_KP,FQuantity=item.FQuantity,FAmount=item.FAmount },
                        p=>p.UseUnit==useUnit&&p.FDocuNO==item.FDocuNO);

                    #region 调整库存
                    //匿名对象需与存过程参数一致
                    var pars = db.GetParameters(new { FAccountDate = item.FAccountDate, UseUnit = item.UseUnit, FSupplierNO = detail.FSupplierNO, FProCompanyNO = detail.FProCompanyNO, FProductionNO = detail.FProductionNO, FProductionTypeNO = detail.FProductionTypeNO, FContainerNO = detail.FContainerNO, FContainerQuantity = detail.FContainerQuantity, FQuantity = detail.FQuantity, FCreateBy = item.FCreateBy, Status = 1, resultState = 1 });
                    int index = db.GetParameterIndex(pars, "resultState");
                    //存储过程返回值暂时未用到.
                    if (index != -1)
                    {
                        pars[index].Direction = System.Data.ParameterDirection.Output;
                    }
                    db.ExecuteStoredProcedure<string>("InOutStorage_UpdateImmeStorage", pars);
                    if (index != -1)
                    {
                        if (string.IsNullOrEmpty(pars[index].Value + ""))
                        {
                            resultState = 0;
                        }
                        else
                        {
                            resultState = int.Parse(pars[index].Value + "");
                        }
                    }
                    #endregion 调整库存

                    db.Commit();
                }
                catch (Exception ex)
                {
                    db.RollBack();
                    throw ex;
                }
                #endregion 数据存入数据库
            }
            return new KeyValuePair<bool, string>(true, item.FDocuNO);
        }

        public void DeleteInventoryStoreItem(List<string> datas)
        {
            foreach(string item in datas)
            {
                var detailData = cpkListAcco.FindEntity(p => p.FDocuListID == item);
                var itemData = cpkConAcco.FindEntity(p => p.FDocuNO == detailData.FDocuNO);
                itemData.FQuantity_KP = itemData.FQuantity_KP - detailData.FQuantity_KP;
                itemData.FAmount_KP = itemData.FAmount_KP-detailData.FPrice_KP * detailData.FQuantity_KP;
                itemData.FQuantity = itemData.FQuantity - detailData.FQuantity;
                itemData.FAmount = itemData.FAmount-detailData.FPrice_KP * detailData.FQuantity_KP;
                cpkConAcco.Update(new { FQuantity_KP = itemData.FQuantity_KP, FAmount_KP = itemData.FAmount_KP, FQuantity = itemData.FQuantity, FAmount = itemData.FAmount }, p => p.FDocuNO == itemData.FDocuNO);
                cpkListAcco.Delete(p => p.FDocuListID == item);
                cpkConAcco.ExecuteStoredProcedure("InOutStorage_UpdateImmeStorage", new { FAccountDate = itemData.FAccountDate, UseUnit = itemData.UseUnit, FSupplierNO = detailData.FSupplierNO, FProCompanyNO = detailData.FProCompanyNO, FProductionNO = detailData.FProductionNO, FProductionTypeNO = detailData.FProductionTypeNO, FContainerNO = detailData.FContainerNO, FContainerQuantity = detailData.FContainerQuantity, FQuantity = detailData.FQuantity, FCreateBy = itemData.FCreateBy, Status = 4, resultState = 1 });
            }
        }
       
        /// <summary>
        /// 盘点审核
        /// </summary>
        /// <param name="datas">单据编号集合</param>
        public void AuditInventoryStoreItem(List<string> datas)
        {
            string useUnit = Configs.GetValue("UseUnit");
            string factoryFlag= Configs.GetValue("FactoryFlag");
            string userCode = OperatorProvider.Provider.GetCurrent().UserCode;
            string userName = OperatorProvider.Provider.GetCurrent().UserName;
            string accountDate= GetDocumentNum.GetNum(useUnit,factoryFlag, "台帐日期成品", userCode, "", "临时");
            
            foreach (string fdocuno in datas)
            {
                #region 更新状态
                cpkConAcco.Update(new { FAuditingStatus = "1", FAccountDate = accountDate, FAuditingBy = userName, FAuditingDate = DateTime.Now.ToString("yyyy-MM-dd"), FAuditingTime = DateTime.Now.ToString("HH:mm:ss") }, p => p.FDocuNO == fdocuno&&p.UseUnit == useUnit);
                cpkListAcco.Update(new { FAuditingStatus = "1", FAccountDate = accountDate, FAuditingBy = userName, FAuditingDate = DateTime.Now.ToString("yyyy-MM-dd"), FAuditingTime = DateTime.Now.ToString("HH:mm:ss") }, p => p.FDocuNO == fdocuno && p.UseUnit == useUnit);
                #endregion 更新状态

                #region 更新库存
                var list = cpkListAcco.FindList(p => p.FDocuNO == fdocuno);
                var item = cpkConAcco.FindEntity(p => p.FDocuNO == fdocuno);
                foreach (var detailItem in list)
                {
                    cpkConAcco.ExecuteStoredProcedure("InOutStorage_UpdateBookStorage", new { UseUnit = useUnit, FAccountDate = accountDate, FDocuTypeNO = detailItem.FDocuTypeNO, FDocuNO = fdocuno, FHappenCompanyNO = item.FHappenComNO, FProCompanyNO = detailItem.FProCompanyNO, FProductionNO=detailItem.FProductionNO, FProductionTypeNO=detailItem.FProductionTypeNO, FContainerNO=detailItem.FContainerNO, FConQuantity=detailItem.FContainerQuantity, FQuantity=detailItem.FQuantity, FPrice=detailItem.FPrice_KP, FStoreNO=detailItem.FStoreNO, FStoreSetNO=detailItem.FStoreSetNO, FCreateBy=detailItem.FCreateBy, Status="3", FRegisterID=detailItem.FRegisterID, FVoucherNo=item.FCredence, FBatch=detailItem.FBatchNo, FDocuListID=detailItem.FDocuListID, FSupplierNO=detailItem.FSupplierNO, FRKDocuNO="" });
                }
                #endregion 更新库存

                #region 数据转入档案
                cpkConAcco.ExecuteStoredProcedure("Pro_AuditInStore", new { FDocuNO = fdocuno, UseUnit = useUnit });
                #endregion 数据转入档案
            }

        }
       
        public void EditInventoryStoreDetail(CPK_42_MX_StoCPKListAccoEntity detail)
        {
            #region 获取原数据
            var oldDetailData = cpkListAcco.FindEntity(p => p.FDocuListID == detail.FDocuListID);
            var itemData = cpkConAcco.FindEntity(p => p.FDocuNO == detail.FDocuNO);
            #endregion 获取原数据

            #region 计算
            itemData.FQuantity_KP = itemData.FQuantity_KP+ detail.FQuantity_KP - oldDetailData.FQuantity_KP;
            itemData.FAmount_KP = itemData.FAmount_KP+ detail.FPrice_KP*detail.FQuantity_KP - oldDetailData.FPrice_KP * oldDetailData.FQuantity_KP;
            itemData.FQuantity = itemData.FQuantity+detail.FQuantity - oldDetailData.FQuantity;
            itemData.FAmount = itemData.FAmount+ detail.FPrice_Settle * detail.FQuantity - oldDetailData.FPrice_Settle * oldDetailData.FQuantity;
            #endregion 计算

            #region 更新数据
            cpkConAcco.Update(new { FQuantity_KP = itemData.FQuantity_KP, FAmount_KP = itemData.FAmount_KP, FQuantity = itemData.FQuantity, FAmount = itemData.FAmount }, p => p.FDocuNO == itemData.FDocuNO);

            cpkListAcco.Update(new { FQuantity_KP=detail.FQuantity_KP, FPrice_KP=detail.FPrice_KP, FQuantity=detail.FQuantity, FPrice_Settle=detail.FPrice_Settle, FFactContent=detail.FFactContent }, p => p.FDocuListID == detail.FDocuListID);

            cpkConAcco.ExecuteStoredProcedure("InOutStorage_UpdateImmeStorage", new { FAccountDate = itemData.FAccountDate, UseUnit = itemData.UseUnit, FSupplierNO = detail.FSupplierNO, FProCompanyNO = detail.FProCompanyNO, FProductionNO = detail.FProductionNO, FProductionTypeNO = detail.FProductionTypeNO, FContainerNO = detail.FContainerNO, FContainerQuantity = detail.FContainerQuantity, FQuantity = detail.FQuantity, FCreateBy = itemData.FCreateBy, Status = 1, resultState = 1 });
            #endregion 更新数据
        }
        public CPK_41_ML_StoCPKConAccoEntity GetEntity(string fdocuno)
        {
            return cpkConAcco.FindEntity(p=>p.FDocuNO==fdocuno);
        }
    }
}
